<?php
namespace Common\Xapi;
/* 
 * 小程序微信支付 
 */  
class xcx{
    public $appid = 'wx745b2ddc10785440';  
    protected $mch_id = '';  
    public $secret = '744a93cc09cadac4c5f572cb9bd9dbcd';
    protected $key = '';
    protected $spbill_create_ip = '120.77.23.41';
    protected $notify_url = 'https://dodoca.weiyuekj.com/Home/XCXapi/notify';
    protected $openid;  
    protected $out_trade_no;  
    protected $body;  
    protected $total_fee;
//
//    public function __construct($option)
//    {
//        $this->appid = $option['appid'];
//        $this->mch_id = $option['mch_id'];
//        $this->secret = $option['secret'];
//        $this->key = $option['key'];
//        $this->spbill_create_ip = $option['spbill_create_ip'];
//        $this->notify_url = $option['$notify_url'];
//    }
    //获取access_token
    public function getAccessToken(){
        //缓存access_token
        $data = S('access_token');
        if(!$data){
            $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->secret;
            $data = $this->curl($url);
            if(isset($data['errcode'])){
                return false;
            }
            S('access_token',$data,7000);
        }
        return $data['access_token'];
    }
    /**
      * 发送自定义的模板消息
     * @param $touser 用户openid
      * @param $template_id 模板ID
      * @param $url 
      * @param $data 
      * @param string $form_id form表单数据
      * @return bool
      */
     public function doSend($touser,$data, $template_id, $url, $form_id)
     {
         $template = array(
             'touser' => $touser,
             'template_id' => $template_id,
             'page' => $url,
             'form_id' => $form_id,
             'data' => $data
         );
         $json_template = json_encode($template);
         $accessToken = $this->getAccessToken();
         $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=" . $accessToken;
         $dataRes = $this->curl($url, urldecode($json_template));
        //file_put_contents('./data/test.txt', var_export($dataRes,true)."\r\n",FILE_APPEND);
         //print_r('<pre>');print_r($dataRes);exit();
         if ($dataRes['errcode'] == 0) {
             return true;
         } else {
             return false;
         }
     }

    /////////////支付功能//////////
    public function pay($openid,$body,$total_fee,$out_trade_no) {  
        $this->openid = $openid;  
        $this->out_trade_no = $out_trade_no;
        $this->body = $body;  
        $this->total_fee = $total_fee;  
        //统一下单接口  
        $return = $this->weixinapp();
        return $return;
    }  
  
  
    //统一下单接口  
    private function unifiedorder() {  

        $parameters = array(  
            'appid' => $this->appid, //小程序ID  
            'mch_id' => $this->mch_id, //商户号  
            'nonce_str' => $this->createNoncestr(), //随机字符串  
            'body' => $this->body,  //商品描述  
            'out_trade_no'=> $this->out_trade_no,  //商户订单号  
            'total_fee' => $this->total_fee,  
            'spbill_create_ip' => $this->spbill_create_ip, //终端IP  
            'notify_url' => $this->notify_url, //通知地址  确保外网能正常访问  
            'openid' => $this->openid, //用户id  
            'trade_type' => 'JSAPI'//交易类型  
        ); 
        //统一下单签名  
        $parameters['sign'] = $this->getSign($parameters);
        S($this->openid,$parameters['sign']);
        $xmlData = $this->arrayToXml($parameters);  
        $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';  
        $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));  
        return $return;  
    }  
  
  
    private static function postXmlCurl($xml, $url, $second = 30)   
    {  
        $ch = curl_init();  
        //设置超时  
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);  
        curl_setopt($ch, CURLOPT_URL, $url);  
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验  
        //设置header  
        curl_setopt($ch, CURLOPT_HEADER, FALSE);  
        //要求结果为字符串且输出到屏幕上  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
        //post提交方式  
        curl_setopt($ch, CURLOPT_POST, TRUE);  
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);  
  
  
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);  
        curl_setopt($ch, CURLOPT_TIMEOUT, 40);  
        set_time_limit(0);  
  
  
        //运行curl  
        $data = curl_exec($ch);  
        //返回结果  
        if ($data) {  
            curl_close($ch);  
            return $data;  
        } else {  
            $error = curl_errno($ch);  
            curl_close($ch);  
            throw new WxPayException("curl出错，错误码:$error");  
        }  
    }  
      
      
      
    //数组转换成xml  
    private function arrayToXml($arr) {  
        $xml = "<root>";  
        foreach ($arr as $key => $val) {  
            if (is_array($val)) {  
                $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";  
            } else {  
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";  
            }  
        }  
        $xml .= "</root>";  
        return $xml;  
    }  
  
  
    //xml转换成数组  
    private function xmlToArray($xml) {  
  
  
        //禁止引用外部xml实体   
  
  
        libxml_disable_entity_loader(true);  
  
  
        $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);  
  
  
        $val = json_decode(json_encode($xmlstring), true);  
  
  
        return $val;  
    }  
  
  
    //微信小程序接口  
    private function weixinapp() {  
        //统一下单接口  
        $unifiedorder = $this->unifiedorder();  
//        print_r($unifiedorder);  
        $parameters = array(  
            'appId' => $this->appid, //小程序ID  
            'timeStamp' => '' . time() . '', //时间戳  
            'nonceStr' => $this->createNoncestr(), //随机串  
            'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //数据包  
            'signType' => 'MD5'//签名方式  
        );  
        //签名  
        $parameters['paySign'] = $this->getSign($parameters);  
        return $parameters;  
    }  
  
  
    //作用：产生随机字符串，不长于32位  
    public function createNoncestr($length = 15) {  
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";  
        $str = "";  
        $len = strlen($chars);
        for ($i = 0; $i < $length; $i++) {  
            $str .= substr($chars, mt_rand(0, $len - 1), 1);  
        }  
        return $str;  
    }  
  
  
    //作用：生成签名  
    public function getSign($Obj) {  
        foreach ($Obj as $k => $v) {  
            $Parameters[$k] = $v;  
        }  
        //签名步骤一：按字典序排序参数  
        ksort($Parameters);  
        $String = $this->formatBizQueryParaMap($Parameters, false);  
        //签名步骤二：在string后加入KEY  
        $String = $String . "&key=" . $this->key;  
        //签名步骤三：MD5加密  
        $String = md5($String);  
        //签名步骤四：所有字符转为大写  
        $result_ = strtoupper($String);  
        return $result_;  
    }  
    
    public function ToUrlParams( $params ){
        $string = '';
        if( !empty($params) ){
            $array = array();
            foreach( $params as $key => $value ){
                $array[] = $key.'='.$value;
            }
            $string = implode("&",$array);
        }
        return $string;
    }
  
    ///作用：格式化参数，签名过程需要使用  
    private function formatBizQueryParaMap($paraMap, $urlencode) {  
        $buff = "";  
        ksort($paraMap);  
        foreach ($paraMap as $k => $v) {  
            if ($urlencode) {  
                $v = urlencode($v);  
            }  
            $buff .= $k . "=" . $v . "&";  
        }  
        $reqPar;  
        if (strlen($buff) > 0) {  
            $reqPar = substr($buff, 0, strlen($buff) - 1);  
        }  
        return $reqPar;  
    }
    /////////////////////////////////
    //////计算购物车里的商品金额/////
    public function countMoney($goods,$couponId=0){
        $goods = stripslashes(html_entity_decode($goods)); 
        $goods = json_decode($goods,TRUE);
        foreach ($goods as $key => $value) {
           $id .= $key.',';
        }
        $id = substr($id,0,-1);

        $data = M()->query('select id,product_price from fs_product where id in('.$id.')');
        $money = 0;
        foreach ($data as $key => $value) {
            $money += $goods[$value['id']] * $value['product_price'];
        }
        //优惠券优惠
        $C = D('Coupon');
        $coupon = $C->getCouponMoney($couponId);
        if($money>=$coupon['limit']){
            $money = $money - $coupon['money'];
            $C->where('id='.$couponId)->save(array('status'=>1));
        }
        
        //配送费
        $express_charges = 0;
        if($money<10){
            $money += $express_charges;
        }

        $money = floatval($money*100);
        $goods = json_encode($goods);
        return array('money'=>$money,'cart'=>$goods,'express_charges'=>$express_charges);
    }
    //////获取购物车里的商品名/////
    public function getGoodsName($goods){
        $goods = stripslashes(html_entity_decode($goods)); 
        $goods = json_decode($goods,TRUE);
        foreach ($goods as $key => $value) {
           $id .= $key.',';
        }
        $id = substr($id,0,-1);
        $data = M()->query('select id,product_name from fs_product where id in('.$id.')');
        foreach ($data as $key => $value) {
            $goodsName .= $value['product_name'].' X'.$goods[$value['id']].';';
        }
        return $goodsName;
    }
    ////客服功能//////
    public function msg(){
        $config = array(
            'appId' => $this->appid,
            'appSecret' => $this->secret,
            'token' => $this->token
            );
        $message = new \Common\model\Message($config);

        $message->valid();

        $object = $message->getObject();

        if($object->MsgType == 'text'){
         $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token='.$message->getAccessToken();
         $data = '{
                     "touser":"'.$object->FromUserName.'",
                     "msgtype":"text",
                     "text":
                     {
                          "content":"小熊之家客服人员稍后会与您联系，谢谢~！"
                     }
                 }';
         $message->curl($url,$data);     
        }
    }
    ///////////////////////////////

      /**
     * curl请求 $field不为空时为post请求
     * @param $url 请求地址
     * @param array $fields post数据
     * @return mixed|string 返回数据
     */
    public function curl($url, $fields){
        $ch = curl_init(); //curl初始化
        curl_setopt($ch,CURLOPT_URL,$url); //设置请求地址
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//数据返回后不要直接显示
        //禁止证书校验
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
        if($fields){
            curl_setopt($ch,CURLOPT_TIMEOUT,30);//响应时间为30秒
            curl_setopt($ch,CURLOPT_POST,1);//设为post请求
            curl_setopt($ch,CURLOPT_POSTFIELDS,$fields);//post数据
        }
        $data = '';
        if(curl_exec($ch)){
            if(curl_errno($ch)){
                echo 'Curl error: ' . curl_error($ch);
                exit;
            }
            //发送成功，获取数据
            $data = curl_multi_getcontent($ch);
        }
        curl_close($ch);
        $curlData = json_decode($data,true);
        if(is_array($curlData)){
            return $curlData;
        }else{
            return $data;
        }
    }
}  